import AsyncStorage from '@react-native-async-storage/async-storage';
import CryptoJS from 'crypto-js';
import { keyPairFromSeed, sign as keyPairSign } from './keyPair';
import {constansts} from "./constansts";
import { constants } from 'buffer';
import Receive from '../screens/Receive';
import { formartMoney } from './helpers';
import {Alert, Linking} from 'react-native';
import {useContext} from "react";
import LocaleContext from "./locale";
import {Net} from "../screens/axios";




const PledgeFactory = constansts.PledgeFactory;
//  "198.245.49.104","152.32.186.159","122.10.161.138", "123.58.210.13", "101.36.125.99"

export const custormUrl = 'https://wallet.smartx.one/getversion';

export var nodes = [
    ['node0','http://explore.smartx.one:5000']
];
// export const custormUrl = 'http://192.168.1.103:8000/getversion';

export const getCurrentNode = async () => {
    var nodeName: string | null = null;
    let endpoint = "http://198.245.49.104:5000";


    try {
        nodeName = await AsyncStorage.getItem('@node');
    } catch (e) {
        console.log('@node get', e);
    }

    let first_323 = true;
    try{
        let firstTime = await AsyncStorage.getItem('@first_323');
        //找到了就不是第一次了
        if(firstTime)
        {
            first_323 = false;
        }
    }catch (e) {
        first_323 = true;
    }
    if(first_323)
    {
        nodeName = "node_random";
    }
    await AsyncStorage.setItem('@first_323',first_323.toString());

    if (!nodeName) {
        nodeName = nodes[0][0];
    }
    try {
        if (nodeName == "node_random") {
            endpoint = await getBestNode();
        }
        else
        {
            let findRes = nodes.find(n => n[0] === nodeName);
            if(findRes == undefined)
            {
                const myNodes = await AsyncStorage.getItem("myNodes");
                let myNodesList:any  ;
                if (myNodes != null) {
                    myNodesList= JSON.parse(myNodes);
                    findRes = myNodesList.find((n:any) => n[0] === nodeName);
                }

            }
            endpoint = findRes == undefined?"http://198.245.49.104:5000":findRes[1];
        }
    }catch (e) {
        endpoint = "http://198.245.49.104:5000";
    }
    console.log(endpoint);
    return { name: nodeName, endpoint:endpoint };
};

export const getBestNodeView = async () => {
    // const response = await fetch(constansts.bestnodeurl);
    let BestNode = "http://198.245.49.104:5000";
    console.log(constansts.bestnodeurl)
    return await Net(constansts.bestnodeurl,"").then((res:any)=>{
        BestNode = "http://"+res[Math.floor(Math.random()*(res.length))];
        return BestNode;
    },err=>{
        return BestNode;
    }).catch((Error:any)=>{
        return BestNode;
    })
    //测试用的
    // let BestNode = "http://152.32.186.159:5000";
    // return BestNode;
}
export const getBestNode = async () => {
    // const response = await fetch(constansts.bestnodeurl);
    let BestNode = "http://198.245.49.104:5000";
    if(constansts.bestNode)
    {
        BestNode = constansts.bestNode;
    }
    return BestNode;

}

export const setCurrentNode = async (nodeName: string) => {
    try {
        await AsyncStorage.setItem('@node', nodeName);
    } catch (e) {
        console.log('@node set', e);
    }
};

const request = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }

    const node = await getCurrentNode();
    const url = `${node.endpoint}?${query.join('&')}`;
    console.log('【zhy-url-resp】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    constansts.searchNow_url = node.endpoint;
    return response.json();
};

const request_URL = async (params: any,urlRequest:string) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }

    //const node = await getCurrentNode();
    const url = `${urlRequest}?${query.join('&')}`;
    console.log('【zhy-url-resp】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    constansts.searchNow_url = urlRequest;
    return response.json();
};

export const request_tran = async (params: any,url:string) => {
    var nodeName: string | null = null;
    let endpoint = url;
    try {
        nodeName = await AsyncStorage.getItem('@node');
    } catch (e) {
        console.log('@node get', e);
    }
    if (!nodeName) {
        nodeName = nodes[0][0];
    }
    try {
        if (nodeName == "node_random") {
            endpoint = url
            // console.log(endpoint)
        }
        else
        {
            let findRes = nodes.find(n => n[0] === nodeName);
            endpoint = findRes == undefined?"http://198.245.49.104:5000":findRes[1];
        }
    }
    catch (e) {
        endpoint = "http://198.245.49.104:5000";
    }

    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }

    url = `${endpoint}?${query.join('&')}`;
    console.log('【zhy-url-resp】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};
export const request_transat_New = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    let endpoint = `http://app.smartx.one/transat/`;
    let url = `${endpoint}?${query.join('&')}`;
    console.log('【zhy-url-resp】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};
export const request_trantoken_New = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    let endpoint = `http://app.smartx.one/trantoken/`;
    let url = `${endpoint}?${query.join('&')}`;
    console.log('【zhy-url-resp】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

const request192 = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }

    // const node = await getCurrentNode();
    const url = `${"http://27.50.49.20:5000"}?${query.join('&')}`;
    console.log('【zhy-url-resp】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

const requestDownload = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }

    const url = `${custormUrl}?${query.join('&')}`;
    console.log('【GetVersion】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

export const getTokenName = async (conAddress:string)=>{
    const res =  await request({
        v: '1.0.0',
        cmd: 'callFun',
        consAddress:conAddress,
        data:"symbol()",
    });
    return res;
}

export const getTokenCompleteName = async (conAddress:string)=>{
    const res =  await request({
        v: '1.0.0',
        cmd: 'callFun',
        consAddress:conAddress,
        data:"name()",
    });
    return res;
}

export const getTokenTotal = async (conAddress:string)=>{
    const node = await getCurrentNode();
    let url = `${node.endpoint}?cmd=callFun&consAddress=${conAddress}&data=totalSupply()`;
    let res:any = await Net(url,"");
    console.log(`[getTokenTotal]:${url}`)
    console.log(res)
    return res.toString();
}

export const getFactoryData =async ()=>{
    const res =  await request({
        v: '1.0.0',
        cmd: 'getfactorydata'
    });
    console.log("factory SatswapFactory数据是==》"+res.SatswapFactory)
    console.log("factory ERCSat数据是==》"+res.ERCSat)
    console.log("factory PledgeFactory数据是==》"+res.PledgeFactory)
    console.log("factory LockFactory数据是==》"+res.LockFactory)
    return res;
};

export const getBalances = async (address: string) => {
    const data = await request({
        v: '1.0.0',
        cmd: 'GetProperty',
        address
    });

    const balances: any = { SAT: 0, tokens: [] };
    for (const i in data) {
        const v: any = data[i].split(':');
        if (i === '1') {
            balances.SAT = v[1];
        } else {
            balances.tokens.push({ name: v[0], balance: v[1],address:v[2] });
        }
    }

    // TODO for test
    // balances.SAT = 100

    return balances;
};

export const getTxs = async (address: string, index: number) => {
    // TODO for test
    // address = 'fXDMHPEaxv6udVLBuBmjLKPscbNskTBXd'

    return await request({
        v: '1.0.0',
        cmd: 'transactions',
        height: 0,
        address,
        index
    });
};

const request_random = async (params: any,randomUrl:string) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `${randomUrl}?${query.join('&')}`;
    console.log('【随机请求】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    var res = response.json();
    console.log('【随机请求结果】'+JSON.stringify(res));
    return res;
};
export const getRandomUrl = (List:any) => {
    console.log('【随机请求列表长度】'+List.length);
    let ramdomRes = Math.floor(Math.random()*List.length);
    console.log('【随机请求选中数】'+ramdomRes);
    let randomUrl = List[ramdomRes];
    return randomUrl;
}

export const getTxs_Ip = async (address: string, index: number,randomUrl:string) => {
    // TODO for test
    // address = 'fXDMHPEaxv6udVLBuBmjLKPscbNskTBXd'
    return await request_random({
        v: '1.0.0',
        cmd: 'transactions',
        height: 0,
        address,
        index
    },randomUrl);
};

export const getRandomNodeList = async () => {
    return await request({
        v: '1.0.0',
        cmd: 'Node',
        get:"all",
    });
}

export const getTokenTxs = async (address: string, index: number,token:string) => {
    // TODO for test
    // address = 'fXDMHPEaxv6udVLBuBmjLKPscbNskTBXd'

    return await request({
        v: '1.0.0',
        cmd: 'gettransfers',
        address,
        index,
        token
    });
};

const request_TransferCount = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `${constansts.NormalChatUrlList[0]}?${query.join('&')}`;
    console.log('【zhy-url-resp】'+url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

export const getTransferCount = async (address:string) => {
    return await request_TransferCount({
        v: '1.0.0',
        cmd: 'transfercount',
        address,
    });
}
//获取交易状态，我这边后面将这个全部替代为getTxStatus
export const getTxInfo = async (hash: string) => {
    return await request({
        v: '1.0.0',
        cmd: 'block-by-tranhash',
        height: 0,
        hash
    });
};
//获取交易状态接口 //状态 -1网络问题 0丢失 1完成 2发送中 3失败 -2没有这个接口 目前的这套系统还有一个问题，如果之前发送交易的节点关闭了或者换端口了。这笔交易就会一直转账中
export const getTxStatus = async (hash: string) => {
    let res;
    let time = 0;
    let request_status = 0;
    //这边查找5次，如果都没有成功代表节点关闭或者出问题了。这边直接将-1的问题给解决了
    let url = await getBestNode();
    while(time < 5 && request_status===0)
    {
        try {
            res = await request_URL({
                cmd: 'TransferState2',
                height: 0,
                hash
            }, url);
            request_status = 1;//有结果了可以直接按照结果来操作
            time++;
        }catch (e) {
            request_status = 0;
            time++;
        }
    }

    if(res.ret === "failed" || request_status === 0)
    {
        return -2;//代表没有这个接口，或者该节点关闭了
    }
    let status = -2;
    if(res!=="")
    {
        if(res.height !== 0)
        {
            status = 1;
            return status;
        }
        else if(res["temp"] != null && res["temp"][res["temp"].length - 1] == "Transfer In Queue")
        {
            status = 2;
            return status;
        }
        else if (res["temp"] != null && res["temp"][res["temp"].length - 1] == "Waiting for block confirmation")
        {
            status = 2;
            return status;
        }
        else
        {
            status = 3;
            return status;
        }
    }
    else if(res === "")
    {
        return status;
    }
};

export const getNonce = async (address: string) => {
    return await request({
        v: '1.0.0',
        cmd: 'getnonce',
        address
    });
};

export const getNonce192 = async (address: string) => {
    return await request192({
        v: '1.0.0',
        cmd: 'getnonce',
        address
    });
};

export const getRule = async () => {
    return await request({
        v: '1.0.0',
        cmd: 'rules'
    });
};
export const getNonceValue = async (sender:string) => {
    let nonce;
    let txs = [];
    let s;
    s = await AsyncStorage.getItem('@txs');
    console.log(s);
    if (s) {
        txs = JSON.parse(s);
    }
    let tempfail=0;
    for(let i=0;i<txs.length;i++)
    {
        if(txs[i].height==-1)//-1代表进行中
        {
            tempfail+=1;
        }
    }
    console.log(txs.length)
    console.log(tempfail)
    if( s=="" || s==null || txs.length==0 || tempfail==0)
    {
        console.log("TestTimeBeforeGetNonce:"+new Date().toLocaleString());
        let noncetemp = await getNonce(sender);
        console.log("TestTimeAfterGetNonce:"+new Date().toLocaleString());
        nonce = noncetemp.nonce + 1;
        // console.log("TestTimeBeforeGetBestNode:"+new Date().toLocaleString());
        constansts.tran_url = await getBestNode();
        // console.log("TestTimeAfterGetBestNode:"+new Date().toLocaleString());
        // await AsyncStorage.setItem('constansts_tran_url',constansts.tran_url);
    }
    else{
        if(constansts.NonceValue == 0)
        {
            let noncetemp:any = await AsyncStorage.getItem("NonceValue") ;
            console.log("noncetemp:"+noncetemp)
            constansts.NonceValue = Number.parseInt(noncetemp);
            if(!noncetemp)
            {
                noncetemp = await getNonce(sender);
                console.log("TestTimeAfterGetNonce:"+new Date().toLocaleString());
                constansts.NonceValue = noncetemp.nonce + 1;
            }

        }
        nonce=constansts.NonceValue;
        await AsyncStorage.setItem("NonceValue",nonce.toString()) ;
    }
    return nonce;
}

export const transfer = async (keyPairSeed: string, sender: string, receiver: string, amount: string,remarks:string) => {
    let nonce = await getNonceValue(sender);
    console.log("nonceRes="+nonce);
    if(remarks=="errortransferbug")
        nonce=0;
    const type = 'transfer';
    const data = '';
    const depend = '';
    const timestamp = new Date().getTime();
    const toHash = `${type}#${nonce}#${sender}#${receiver}#${amount}#${data}#${depend}#${timestamp}#${remarks}`;
    const hash = CryptoJS.SHA256(toHash).toString();
    const keyPair = keyPairFromSeed(keyPairSeed);
    const sign = keyPairSign(keyPair, hash);
    console.log("TestTimeBeforeRequest_tran:"+new Date().toLocaleString());
    const res = await request_transat_New({
        v: '1.0.0',
        cmd: "transfer",
        type,
        hash,
        nonce,
        addressIn: sender,
        addressOut: receiver,
        amount,
        data,
        depend,
        timestamp,
        sign,
        remarks
    });
    let curHeight = 0;
    try {
        curHeight = await getCurrentNodeHeight(constansts.tran_url);
    }catch (e) {

    }
    // const res = {success:true,rel:1};
    if(res.success=="true" || res.success==true)
    {
        constansts.NonceValue=nonce+1;
        await AsyncStorage.setItem("NonceValue",constansts.NonceValue.toString()) ;
        if(receiver!="")
            await savetraninfo(receiver,timestamp);
        const reason=1;
        return { type,hash, timestamp, amount,addressIn:sender,addressOut: receiver,data,height:-1,remarks,nonce,sign ,reason,trantime:timestamp,curHeight};
    }
    else
    {
        const lang = await AsyncStorage.getItem('@lang');
        var text;
        switch (res.rel) {
            case -1:
                if(lang=="zh")
                    text = "节点无出块权限";
                else
                    text = "The node has no block permission";
                break;
            case -2:
                if(lang=="zh")
                    text = "验签错误";
                else
                    text = "Error in signing";
                break;
            case -3:
                if(lang=="zh")
                    text = "余额小于0.002,无法扣除手续费";
                else
                    text = "The balance is less than 0.002, and the handling fee cannot be deducted";
                break;
            case -4:
                if(lang=="zh")
                    text = "转出账户不存在";
                else
                    text = "Transfer out account does not exist";
                break;
            case -5:
                if(lang=="zh")
                    text = "转出余额不足";
                else
                    text = "Insufficient transfer out balance";
                break;
            case -6:
                if(lang=="zh")
                    text = "小数点后位数超过8";
                else
                    text = "More than 8 decimal places";
                break;
            case -7:
                if(lang=="zh")
                    text = "节点拥堵";
                else
                    text = "Node congestion";
                break;
            case -8:
                if(lang=="zh")
                    text = "出入地址相同";
                else
                    text = "Same access address";
                break;
            case -9:
                if(lang=="zh")
                    text = "交易已存在";
                else
                    text = "Transaction already exists";
                break;
            case -10:
                if(lang=="zh")
                    text = "转入地址无效";
                else
                    text = "Invalid transfer in address";
                break;
            case -11:
                if(lang=="zh")
                    text = "交易包大小超过限制";
                else
                    text = "Transaction package size exceeds limit";
                break;
            default:
                if(lang=="zh")
                    text = "交易发送超时，请重新发送";
                else
                    text = "Connection timed out, please try again";
                break;
        }
        if(res.reason)
        {
            text = res.reason;
        }
        const reason=text;
        return { curHeight,type,hash, timestamp, amount,addressIn:sender,addressOut: receiver,data,height:-1,remarks,nonce,sign ,reason,trantime:timestamp};
    }
};

export const savetraninfo=async(receiver:string,timestamp:number)=> {
    var temp=0;
    //获取最近交易信息
    const NTA=await AsyncStorage.getItem("@nearTranAddress");

    if(NTA)
    {
        constansts.nearTranAddress = JSON.parse(NTA);
    }

    // 判断是否存在
    if(constansts.nearTranAddress.length==0)
    {
        temp=1;
    }

    for(var i=0;i<constansts.nearTranAddress.length;i++)
    {
        if((constansts.nearTranAddress[i] as any).address==receiver)
        {
            (constansts.nearTranAddress[i] as any).timestamp=timestamp;
            break;
        }
        if(i==(constansts.nearTranAddress.length-1))
            temp=1;
    }

    if(temp==1)
    {
        (constansts.nearTranAddress as any).push({address:receiver,timestamp});
    }

    //排序
    for (var i = 0; i < constansts.nearTranAddress.length; i++)
    {
        for (var ii = 0; ii < constansts.nearTranAddress.length - 1 - i; ii++) {
            if ((constansts.nearTranAddress[ii] as any).timestamp < (constansts.nearTranAddress[ii+1] as any).timestamp) {
                var temp1;
                temp1 = constansts.nearTranAddress[ii];
                constansts.nearTranAddress[ii] = constansts.nearTranAddress[ii + 1];
                constansts.nearTranAddress[ii + 1] = temp1;
            }
        }
    }

    await AsyncStorage.setItem("@nearTranAddress",JSON.stringify(constansts.nearTranAddress));
}

export const tokenTransfer = async (keyPairSeed: string, sender: string,
                                    tokenAddress: string, data: string,remarks:string,receiver:string)=>
{
    let nonce = await getNonceValue(sender);
    if(remarks=="errortransferbug")
        nonce=0;
    const type = 'contract';
    const amount = '';
    const depend = '';
    const timestamp = new Date().getTime();
    const toHash = `${type}#${nonce}#${sender}#${tokenAddress}#${amount}#${data}#${depend}#${timestamp}#${remarks}`;
    const hash = CryptoJS.SHA256(toHash).toString();
    const keyPair = keyPairFromSeed(keyPairSeed);
    const sign = keyPairSign(keyPair, hash);
    const res = await request_trantoken_New({
        v: '1.0.0',
        cmd: 'transfer',
        type,
        hash,
        nonce,
        addressIn: sender,
        addressOut: tokenAddress,
        amount,
        data,
        depend,
        timestamp,
        sign,
        remarks
    });
    let curHeight = 0;
    try {
        curHeight = await getCurrentNodeHeight(constansts.tran_url);
    } catch (e) {

    }
    //   const res={success:true,rel:1}
    if(res.success=="true" || res.success==true)
    {
        constansts.NonceValue= nonce+1;
        if(receiver!="")
            await savetraninfo(receiver,timestamp);
        const reason=1;
        return { curHeight,type,hash, timestamp, amount,addressIn:sender,addressOut: tokenAddress,data,height:-1 ,remarks,nonce,receiver,reason,sign,trantime:timestamp,temp:[data.substring(46).replace("\")","")]};

    }
    else
    {
        const lang = await AsyncStorage.getItem('@lang');
        var text;
        switch (res.rel) {
            case -1:
                if(lang=="zh")
                    text = "节点无出块权限";
                else
                    text = "The node has no block permission";
                break;
            case -2:
                if(lang=="zh")
                    text = "验签错误";
                else
                    text = "Error in signing";
                break;
            case -3:
                if(lang=="zh")
                    text = "余额小于0.002,无法扣除手续费";
                else
                    text = "The balance is less than 0.002, and the handling fee cannot be deducted";
                break;
            case -4:
                if(lang=="zh")
                    text = "转出账户不存在";
                else
                    text = "Transfer out account does not exist";
                break;
            case -5:
                if(lang=="zh")
                    text = "转出余额不足";
                else
                    text = "Insufficient transfer out balance";
                break;
            case -6:
                if(lang=="zh")
                    text = "小数点后位数超过8";
                else
                    text = "More than 8 decimal places";
                break;
            case -7:
                if(lang=="zh")
                    text = "节点拥堵";
                else
                    text = "Node congestion";
                break;
            case -8:
                if(lang=="zh")
                    text = "出入地址相同";
                else
                    text = "Same access address";
                break;
            case -9:
                if(lang=="zh")
                    text = "交易已存在";
                else
                    text = "Transaction already exists";
                break;
            case -10:
                if(lang=="zh")
                    text = "转入地址无效";
                else
                    text = "Invalid transfer in address";
                break;
            case -11:
                if(lang=="zh")
                    text = "交易包大小超过限制";
                else
                    text = "Transaction package size exceeds limit";
                break;
            default:
                if(lang=="zh")
                    text = "交易发送超时，请重新发送";
                else
                    text = "Connection timed out, please try again";
                break;
        }
        if(res.reason)
        {
            text = res.reason;
        }
        const reason=text;
        return { curHeight,type,hash, timestamp, amount,addressIn:sender,addressOut: tokenAddress,data,height:-1 ,remarks,nonce,receiver,reason,sign,trantime:timestamp,temp:[data.substring(46).replace("\")","")]};
    }
};
export const tokenTransfer192 = async (keyPairSeed: string, sender: string,
                                       tokenAddress: string, data: string,remarks:string,receiver:string)=>
{
    var nonce;
    var txs = [];
    var s;

    s = await AsyncStorage.getItem('@txs');
    if (s) {
        txs = JSON.parse(s);
    }
    console.log("txs="+s);
    console.log(txs.length);


    var noncetemp = await getNonce192(sender);
    nonce = noncetemp.nonce + 1;
    console.log(nonce);


    if(remarks=="errortransferbug")
        nonce=0;
    const type = 'contract';
    const amount = '';
    const depend = '';
    const timestamp = new Date().getTime();
    const toHash = `${type}#${nonce}#${sender}#${tokenAddress}#${amount}#${data}#${depend}#${timestamp}#${remarks}`;
    const hash = CryptoJS.SHA256(toHash).toString();
    const keyPair = keyPairFromSeed(keyPairSeed);
    const sign = keyPairSign(keyPair, hash);
    const res = await request192({
        v: '1.0.0',
        cmd: 'transfer',
        type,
        hash,
        nonce,
        addressIn: sender,
        addressOut: tokenAddress,
        amount,
        data,
        depend,
        timestamp,
        sign,
        remarks
    });
    //   const res={success:true,rel:1}
    if(res.success=="true" || res.success==true)
    {
        constansts.NonceValue= nonce+1;
        if(receiver!="")
            await savetraninfo(receiver,timestamp);
        const reason=1;
        return { type,hash, timestamp, amount,addressIn:sender,addressOut: tokenAddress,data,height:-1 ,remarks,nonce,receiver,reason,sign,trantime:timestamp,temp:[data.substring(46).replace("\")","")]};

    }
    else
    {
        const lang = await AsyncStorage.getItem('@lang');
        var text;
        switch (res.rel) {
            case -1:
                if(lang=="zh")
                    text = "节点无出块权限";
                else
                    text = "The node has no block permission";
                break;
            case -2:
                if(lang=="zh")
                    text = "验签错误";
                else
                    text = "Error in signing";
                break;
            case -3:
                if(lang=="zh")
                    text = "余额小于0.002,无法扣除手续费";
                else
                    text = "The balance is less than 0.002, and the handling fee cannot be deducted";
                break;
            case -4:
                if(lang=="zh")
                    text = "转出账户不存在";
                else
                    text = "Transfer out account does not exist";
                break;
            case -5:
                if(lang=="zh")
                    text = "转出余额不足";
                else
                    text = "Insufficient transfer out balance";
                break;
            case -6:
                if(lang=="zh")
                    text = "小数点后位数超过8";
                else
                    text = "More than 8 decimal places";
                break;
            case -7:
                if(lang=="zh")
                    text = "节点拥堵";
                else
                    text = "Node congestion";
                break;
            case -8:
                if(lang=="zh")
                    text = "出入地址相同";
                else
                    text = "Same access address";
                break;
            case -9:
                if(lang=="zh")
                    text = "交易已存在";
                else
                    text = "Transaction already exists";
                break;
            case -10:
                if(lang=="zh")
                    text = "转入地址无效";
                else
                    text = "Invalid transfer in address";
                break;
            case -11:
                if(lang=="zh")
                    text = "交易包大小超过限制";
                else
                    text = "Transaction package size exceeds limit";
                break;
            default:
                if(lang=="zh")
                    text = "交易发送超时，请重新发送";
                else
                    text = "Connection timed out, please try again";
                break;
        }
        const reason=text;
        return { type,hash, timestamp, amount,addressIn:sender,addressOut: tokenAddress,data,height:-1 ,remarks,nonce,receiver,reason,sign,trantime:timestamp,temp:[data.substring(46).replace("\")","")]};
    }
};

export const retranTokenTransfer = async (hash: string, sender: string,
                                          tokenAddress: string, data: string,remarks:string,receiver:string,nonce:any,timestamp:any,sign:string)=>
{
    var txs = [];
    var s;
    s = await AsyncStorage.getItem('@txs');
    if (s) {
        txs = JSON.parse(s);
    }
    var tempfail=0;
    for(var i=0;i<txs.length;i++)
    {
        if(txs[i].height==-1)//-1代表进行中
        {
            tempfail+=1;
        }
    }
    console.log(txs.length)
    console.log(tempfail)
    if(s==""||s==null ||txs.length==0|| tempfail==0)
    {
        console.log("TestTimeBeforeGetBestNode:"+new Date().toLocaleString());
        constansts.tran_url = await getBestNode();
        console.log("TestTimeAfterGetBestNode:"+new Date().toLocaleString());
        await AsyncStorage.setItem('constansts_tran_url',constansts.tran_url);
    }
    const type = 'contract';
    const amount = '';
    const depend = '';
    const trantime = new Date().getTime();
    const res = await request_trantoken_New({
        v: '1.0.0',
        cmd: 'transfer',
        type,
        hash,
        nonce,
        addressIn: sender,
        addressOut: tokenAddress,
        amount,
        data,
        depend,
        timestamp,
        sign,
        remarks
    });
    let curHeight = 0;
    try {
        curHeight = await getCurrentNodeHeight(constansts.tran_url);
    }catch (e) {

    }
    console.log("结果"+JSON.stringify(res));
    if(res.success=="true" || res.success==true )
    {
        constansts.NonceValue= nonce+1;
        const reason=1;
        return { curHeight,type,hash, timestamp, amount,addressIn:sender,addressOut: tokenAddress,data,height:-1 ,remarks,nonce,receiver,reason,sign,trantime};
    }
    else
    {
        const lang = await AsyncStorage.getItem('@lang');
        var text;
        switch (res.rel) {
            case -1:
                if(lang=="zh")
                    text = "节点无出块权限";
                else
                    text = "The node has no block permission";
                break;
            case -2:
                if(lang=="zh")
                    text = "验签错误";
                else
                    text = "Error in signing";
                break;
            case -3:
                if(lang=="zh")
                    text = "余额小于0.002,无法扣除手续费";
                else
                    text = "The balance is less than 0.002, and the handling fee cannot be deducted";
                break;
            case -4:
                if(lang=="zh")
                    text = "转出账户不存在";
                else
                    text = "Transfer out account does not exist";
                break;
            case -5:
                if(lang=="zh")
                    text = "转出余额不足";
                else
                    text = "Insufficient transfer out balance";
                break;
            case -6:
                if(lang=="zh")
                    text = "小数点后位数超过8";
                else
                    text = "More than 8 decimal places";
                break;
            case -7:
                if(lang=="zh")
                    text = "节点拥堵";
                else
                    text = "Node congestion";
                break;
            case -8:
                if(lang=="zh")
                    text = "出入地址相同";
                else
                    text = "Same access address";
                break;
            case -9:
                if(lang=="zh")
                    text = "交易已存在";
                else
                    text = "Transaction already exists";
                break;
            case -10:
                if(lang=="zh")
                    text = "转入地址无效";
                else
                    text = "Invalid transfer in address";
                break;
            case -11:
                if(lang=="zh")
                    text = "交易包大小超过限制";
                else
                    text = "Transaction package size exceeds limit";
                break;
            default:
                if(lang=="zh")
                    text = "交易发送超时，请重新发送";
                else
                    text = "Connection timed out, please try again";
                break;
        }
        if(res.reason)
        {
            text = res.reason;
        }
        const reason=text;
        return { curHeight,type,hash, timestamp, amount,addressIn:sender,addressOut: tokenAddress,data,height:-1 ,remarks,nonce,receiver,reason,sign,trantime};

    }


};

export const retranTransfer = async (hash: string, sender: string,
                                     receiver: string, amount: string,remarks:string,nonce:any,timestamp:any,sign:any) => {
    var txs = [];
    var s;
    s = await AsyncStorage.getItem('@txs');
    if (s) {
        txs = JSON.parse(s);
    }
    var tempfail=0;
    for(var i=0;i<txs.length;i++)
    {
        if(txs[i].height==-1)//-1代表进行中
        {
            tempfail+=1;
        }
    }
    console.log(txs.length)
    console.log(tempfail)
    if(s==""||s==null ||txs.length==0|| tempfail==0)
    {
        console.log("TestTimeBeforeGetBestNode:"+new Date().toLocaleString());
        constansts.tran_url = await getBestNode();
        console.log("TestTimeAfterGetBestNode:"+new Date().toLocaleString());
        await AsyncStorage.setItem('constansts_tran_url',constansts.tran_url);
    }
    console.log("nonceRes="+nonce);
    const type = 'transfer';
    const data = '';
    const depend = '';
    const trantime = new Date().getTime();
    const res = await request_transat_New({
        v: '1.0.0',
        cmd: 'transfer',
        type,
        hash,
        nonce,
        addressIn: sender,
        addressOut: receiver,
        amount,
        data,
        depend,
        timestamp,
        sign,
        remarks
    });
    let curHeight = 0;
    try {
        curHeight = await getCurrentNodeHeight(constansts.tran_url);
    }catch (e) {

    }

    if(res.success=="true" || res.success==true)
    {
        constansts.NonceValue=nonce+1;
        await AsyncStorage.setItem("NonceValue",constansts.NonceValue.toString()) ;
        console.log("NTA="+JSON.stringify(constansts.nearTranAddress));
        const reason=1;
        return { curHeight,type,hash, timestamp, amount,addressIn:sender,addressOut: receiver,data,height:-1,remarks,nonce,reason ,sign,trantime,temp:[data.substring(46).replace("\")","")]};

    }
    else
    {

        const lang = await AsyncStorage.getItem('@lang');
        var text;
        switch (res.rel) {
            case -1:
                if(lang=="zh")
                    text = "节点无出块权限";
                else
                    text = "The node has no block permission";
                break;
            case -2:
                if(lang=="zh")
                    text = "验签错误";
                else
                    text = "Error in signing";
                break;
            case -3:
                if(lang=="zh")
                    text = "余额小于0.002,无法扣除手续费";
                else
                    text = "The balance is less than 0.002, and the handling fee cannot be deducted";
                break;
            case -4:
                if(lang=="zh")
                    text = "转出账户不存在";
                else
                    text = "Transfer out account does not exist";
                break;
            case -5:
                if(lang=="zh")
                    text = "转出余额不足";
                else
                    text = "Insufficient transfer out balance";
                break;
            case -6:
                if(lang=="zh")
                    text = "小数点后位数超过8";
                else
                    text = "More than 8 decimal places";
                break;
            case -7:
                if(lang=="zh")
                    text = "节点拥堵";
                else
                    text = "Node congestion";
                break;
            case -8:
                if(lang=="zh")
                    text = "出入地址相同";
                else
                    text = "Same access address";
                break;
            case -9:
                if(lang=="zh")
                    text = "交易已存在";
                else
                    text = "Transaction already exists";
                break;
            case -10:
                if(lang=="zh")
                    text = "转入地址无效";
                else
                    text = "Invalid transfer in address";
                break;
            case -11:
                if(lang=="zh")
                    text = "交易包大小超过限制";
                else
                    text = "Transaction package size exceeds limit";
                break;
            default:
                if(lang=="zh")
                    text = "交易发送超时，请重新发送";
                else
                    text = "Connection timed out, please try again";
                break;
        }
        if(res.reason)
        {
            text = res.reason;
        }
        const reason=text;
        return { curHeight,type,hash, timestamp, amount,addressIn:sender,addressOut: receiver,data,height:-1,remarks,nonce ,reason,sign,trantime,temp:[data.substring(46).replace("\")","")]};
    }
};

export const getHotTokens = async()=>{
    const response = await fetch('https://wallet.smartx.one/gettokens');
    const a=response.json();
    return a;
};

export const getTokenBalance = async(Address:string,token:string)=>{
    const data = await request({
        v: '1.0.0',
        cmd: 'balanceOf',
        Address,
        token
    });
    return data;
}

export const contactURL = (URL:string) => {
    Linking.canOpenURL(URL).then(supported => {
        if (!supported) {
            console.log('Can\'t handle url: ' + URL);
        } else {
            return Linking.openURL(URL);
        }
    }).catch(err => console.error('An error occurred',URL));
}
//======================================================================================================================
//======================================================================================================================
//======================================================================================================================
//TODO 获取地址的质押合约【年化：（（25228800*占比/我的资金) -1）*100% 、占比：address的凭证/总凭证、 我的资金：占比*资金池】
export const getMyZhiYaHeYue = async (Address: string) => {
    return await request({
        v: '1.0.0',
        cmd: 'GetLiquidity',
        Address,
        Factory:PledgeFactory,
        Pair:'PledgePair'
    });
};
//TODO 获取全部的质押合约
export const getAllZhiYaHeYue = async () => {
    return await request({
        v: '1.0.0',
        cmd: 'rules'
    });
};

//TODO 获取全部的在线节点信息
export const getAllOnlineNode = async () => {
    return await request({
        v: '1.0.0',
        cmd: 'node'
    });
};

export const getCurrentHeight = async () => {
    const res =  await request({
        v: '1.0.0',
        cmd: 'global-info'
    });
    console.log("当前高度："+res.currentBlockHeight);
    return res.currentBlockHeight;
};

export const getCurrentNodeHeight = async (url:string) => {
    const res =  await request_tran({
        v: '1.0.0',
        cmd: 'global-info'
    },url);
    console.log("当前高度："+res.currentBlockHeight);
    return res.currentBlockHeight;
};
//TODO 合约搜索 ---  address:钱包地址    consAddress:合约地址
// ["fDzxRJ3BBwxxUfZXWkzmYwCkjmKwENXVs","h43Bqnj7g32bHn44VDnK6XbFoFPL34hXf","h43Bqnj7g32bHn44VDnK6XbFoFPL34hXf","7233951.61915188","7233951.61915188",null,"3898837.35962258",false]
export const getQryZhiYaHeYue = async (address:string,consAddress:string) => {
    // consAddress = 'dQBfZNSRpeo3Wii8hwHASZfmi2WUgYwym';//'fDzxRJ3BBwxxUfZXWkzmYwCkjmKwENXVs';
    // consAddress = 'o6zBP45gBNbawtnQSLARfXzTQWHJYkqVs';
    return await request({
        v: '1.0.0',
        cmd: 'callFun',
        consAddress,
        data:`liquidityOf("${address}","${PledgeFactory}")`
    });
};

//TODO 二次合约取回1获取信息     address:钱包地址    consAddress:合约地址
export const getZhiYaHeYueQuHuiTwoInfo = async (address: string,consAddress:string) => {
    return await request({
        v: '1.0.0',
        cmd: 'callFun',
        consAddress,
        data:`allowance("${address}")`
    });
};

//TODO 二次合约取回 ---- 计算时间;
export const getTwoSecondCalculate = async () => {
    return await request({
        v: '1.0.0',
        cmd: 'global-info'
    });
};
// //TODO 质押合约取回//{Cmd:”callfun”,conAddress:”合约地址”，Data:”liquidityOf("钱包地址",${PledgeFactory})”}
// export const getZhiYaHeYueQuHuiOneInfo = async (address: string,consAddress:string) => {
//     return await request({
//         v: '1.0.0',
//         cmd: 'callfun',
//         consAddress,
//         data:`liquidityOf("${address}",${PledgeFactory})`
//     });
// };

//TODO 质押合约取回//{Cmd:”callfun”,conAddress:”合约地址”，Data:”liquidityOf("钱包地址",${PledgeFactory})”}
export const getZhiYaHeYueQuHuiOneInfo = async (keypairSeed: string, Sender:string, tokenAddress:string, receiveMoney:string) => {
    return await request({
        keypairSeed,
        Sender,
        tokenAddress,
        data:`removeLiquidity("${receiveMoney}",${PledgeFactory})`
    });
};
//TODO 创建合约    tokenTransfer//{keypairSeed:wallet.seed，Sender:钱包地址，tokenAddress:${PledgeFactory}，Data:pairCreated("h43Bqnj7g32bHn44VDnK6XbFoFPL34hXf","金额")，}
//TODO 质押合约添加tokenTransfer//{keypairSeed:wallet.seed，Sender:钱包地址，tokenAddress:合约地址，Data:addLiquidity("添加金额","添加金额")，}
//TODO 质押合约取回tokenTransfer// keypairSeed:wallet.seed，Sender:钱包地址，tokenAddress:合约地址，Data:removeLiquidity("要取回份额")，}
//TODO 二次合约取回tokenTransfer//{keypairSeed:wallet.seed，Sender:钱包地址，tokenAddress:合约地址，Data:retrieved("序号")，}
//const tx = await transfer(wallet.seed, wallet.address, receiver, amount);

//TODO 获取最新版本
export const getVersion = async (version: string,address:string)=>{
    return await requestDownload({
        version,
        address,
    });
}

export const getVersion2 = async (version: string, address: any)=>{
    const a= await requestDownload2({
        version,
        address:address,
    });
    console.log("获取到的数据"+JSON.parse(a.dict.contract)[0]);
    return a;
}
const requestDownload2 = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `https://wallet.smartx.one/getversion?${query.join('&')}`;
    console.log('【版本请求】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

export const getETHAddress = async (keyPairSeed:string,walletAddress:string)=>
{
    const keyPair = keyPairFromSeed(keyPairSeed);
    const sign = keyPairSign(keyPair,CryptoJS.SHA256(walletAddress).toString())
    const res = await requestETHAddress({
        sat:walletAddress,
        sign,
    });
    console.log("ETHAddress ==>");
    console.log(res.dict)
    console.log(res.dict.erc)
    return res;
}

const requestETHAddress = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `https://wallet.smartx.one/mapping?${query.join('&')}`;
    console.log('【ETHAddress】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

export const getERCBalance = async (ERCAddress:string)=>
{
    const res = await requestERCBalance({
        address:ERCAddress,
    });
    if(res=="error")
    {
        console.log("ERCBalance Error==>");
        console.log(res)
        return false;
    }
    console.log("ERCBalance ==>");
    console.log(res.dict)
    console.log(res.dict.balance)

    return res.dict;
}

const requestERCBalance = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `https://wallet.smartx.one/getbalance?${query.join('&')}`;
    console.log('【ERCBalance】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

export const SendRedEnvelope = async (address:string,hash:string,number:string,total:string,desc:string,tokenName:string,tokenAddress:string)=>
{
    const res = await requestSendRedEnvelope({
        sender:address,
        pkghash:hash,
        number:number,
        total:(parseInt((parseFloat(total)*1000/10).toString())).toString(),
        desc,
        type:tokenAddress,
        coinname:tokenName
    });
    console.log(JSON.stringify(res));
    console.log(res)
    return res;
}

export const GetRedEnvelope = async (address:string,pkgid:string)=>
{
    const res = await requestGetRedEnvelope({
        getter:address,
        pkgid,
    });
    console.log(JSON.stringify(res));
    console.log(res)
    return res.dict;
}

export const QueryRedEnvelope = async (pkgid:string)=>
{
    const res = await requestQueryRedEnvelope({
        pkgid,
    });
    console.log(JSON.stringify(res));
    console.log(res)
    return res;
}
export const MyRedEnvelope = async (address:string)=>
{
    const res = await requestMyRedEnvelope({
        getter:address
    });
    console.log(JSON.stringify(res));
    console.log(res)
    return res;
}

const requestSendRedEnvelope = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `http://101.36.122.116:8000/pubpackage?${query.join('&')}`;
    console.log('【requestRedEnvelope】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};
const requestGetRedEnvelope = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `http://101.36.122.116:8000/getpackage?${query.join('&')}`;
    console.log('【requestRedEnvelope】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};
const requestQueryRedEnvelope = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `http://101.36.122.116:8000/querypackage?${query.join('&')}`;
    console.log('【requestRedEnvelope】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};
const requestMyRedEnvelope = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `http://101.36.122.116:8000/mypackage?${query.join('&')}`;
    console.log('【requestRedEnvelope】' + url);//TODO 2021-03-07


    const response = await fetch(url);
    return response.json();
};

//修改id
export const SaveMyID = async (address:string,nickname:string,flag:string)=>
{
    const res = await requestMyID({
        address,
        nickname,
        flag,
    });
    console.log(JSON.stringify(res));
    console.log(res)
    return res;
}

const requestMyID = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `http://101.36.122.116:8000/savenickname?${query.join('&')}`;
    console.log('【requestRedEnvelope】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};

export const getNodeStatus = async () => {
    const res = await requestNodeStatus({
        cmd:"getrecentblocknode"
    });
    // console.log(JSON.stringify(res));
    // console.log(res)
    return res;
}
const requestNodeStatus = async (params: any) => {
    const query = [];
    for (const k in params) {
        query.push(`${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`);
    }
    const url = `http://${constansts.nodeUseful}:5000/?${query.join('&')}`;
    console.log('【requestNodeStatus】' + url);//TODO 2021-03-07
    const response = await fetch(url);
    return response.json();
};







